feat: Add third-party evaluator CLI integration (DeepEval + Autoevals)#1779
Open
stone-coding wants to merge 6 commits into
Open
feat: Add third-party evaluator CLI integration (DeepEval + Autoevals)#1779stone-coding wants to merge 6 commits into
stone-coding wants to merge 6 commits into
Conversation
…Eval + Autoevals)
…support - DeepEval template: add /tmp workaround + DEEPEVAL_TELEMETRY_OPT_OUT for Lambda - Autoevals template: fix scorer= → metric= to match SDK API - Rename --from-3p-library → --3p-library - Add --param key=value (repeatable) for metric constructor kwargs - Add --parameters-file for JSON file of kwargs - Add parseParamFlags() utility + unit tests - --param and --parameters-file are mutually exclusive
- Add e2e-tests/third-party-eval-lifecycle.test.ts: full lifecycle test for DeepEval + Autoevals 3P evaluators (create → add → deploy → invoke → run eval) - Fix autoevals template: params go to AutoevalsAdapter (not metric constructor) - Add openai>=1.0.0 to autoevals pyproject.toml (required by LLM-based scorers)
chianhw
reviewed
Jul 22, 2026
| ) | ||
| from bedrock_agentcore.evaluation.custom_code_based_evaluators.third_party.autoevals import AutoevalsAdapter | ||
|
|
||
| adapter = AutoevalsAdapter(metric={{ EvaluatorClass }}(), {{{ EvaluatorParams }}}) |
chianhw
reviewed
Jul 22, 2026
| if (cliOptions.instructions) fail('--instructions cannot be used with --type code-based'); | ||
| if (cliOptions.ratingScale) fail('--rating-scale cannot be used with --type code-based'); | ||
| } | ||
|
|
There was a problem hiding this comment.
We don't handle evalType === 'llm-as-a-judge' && threePLibrary?
Add validation guard so that explicitly passing --type llm-as-a-judge with --3p-library fails with a clear error message instead of silently proceeding into an invalid state.
There was a problem hiding this comment.
Pull request overview
This PR extends AgentCore CLI evaluator support by adding a registry-driven integration for third-party evaluator libraries (DeepEval and Autoevals), including new CLI flags for metric selection and constructor parameters, and new template assets for scaffolding.
Changes:
- Added
--3p-library,--metric, repeatable--param, and--parameters-file(plus--memory) for third-party evaluator scaffolding. - Introduced a registry (
THIRD_PARTY_EVALUATOR_LIBRARIES) with per-library defaults (timeout/memory) and per-metric runtime warnings. - Added new evaluator template assets (DeepEval/Autoevals) and an E2E lifecycle test covering create → add → deploy → invoke → run eval.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/schema/schemas/primitives/evaluator.ts | Extends managed code-based evaluator schema to optionally accept Lambda memory size. |
| src/schema/llm-compacted/agentcore.ts | Mirrors the new optional memorySizeMb field in the compacted TS interface. |
| src/cli/templates/EvaluatorRenderer.ts | Adds a renderer for third-party evaluator templates with structured template data. |
| src/cli/primitives/EvaluatorPrimitive.ts | Implements third-party evaluator registry, CLI parsing/validation, config generation, and template scaffolding. |
| src/cli/primitives/tests/EvaluatorPrimitive.test.ts | Adds unit tests for registry defaults, config generation, and param parsing helpers. |
| src/assets/evaluators/deepeval-lambda/* | Adds DeepEval evaluator scaffold (lambda handler + pyproject + IAM policy). |
| src/assets/evaluators/autoevals-lambda/* | Adds Autoevals evaluator scaffold (lambda handler + pyproject + IAM policy). |
| src/assets/tests/snapshots/assets.snapshot.test.ts.snap | Updates asset snapshot listing to include new evaluator template directories. |
| e2e-tests/third-party-eval-lifecycle.test.ts | Adds an E2E test covering DeepEval + Autoevals evaluator lifecycle (skipped when env can’t run). |
| .gitignore | Ignores test-e2e-output/ directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+137
to
+162
| export function jsonToKwargs(json: string): string { | ||
| const obj = JSON.parse(json) as Record<string, unknown>; | ||
| return Object.entries(obj) | ||
| .map(([key, value]) => `${key}=${jsonToPythonValue(value)}`) | ||
| .join(', '); | ||
| } | ||
|
|
||
| export function parseParamFlags(params: string[]): string { | ||
| return params | ||
| .map(param => { | ||
| const eqIndex = param.indexOf('='); | ||
| if (eqIndex === -1) { | ||
| throw new Error(`"${param}" is not in key=value format`); | ||
| } | ||
| const key = param.slice(0, eqIndex); | ||
| const rawValue = param.slice(eqIndex + 1); | ||
| let value: unknown; | ||
| try { | ||
| value = JSON.parse(rawValue); | ||
| } catch { | ||
| value = rawValue; | ||
| } | ||
| return `${key}=${jsonToPythonValue(value)}`; | ||
| }) | ||
| .join(', '); | ||
| } |
Comment on lines
+403
to
+410
| if (threePLibrary) { | ||
| if (!cliOptions.metric) fail('--metric is required when using --3p-library'); | ||
| if (cliOptions.model) fail('--model cannot be used with --3p-library'); | ||
| if (cliOptions.instructions) fail('--instructions cannot be used with --3p-library'); | ||
| if (cliOptions.ratingScale) fail('--rating-scale cannot be used with --3p-library'); | ||
| if (cliOptions.lambdaArn) fail('--lambda-arn cannot be used with --3p-library'); | ||
| if (cliOptions.config) fail('--config cannot be used with --3p-library'); | ||
| } |
Comment on lines
+640
to
+659
| private buildThirdPartyConfig( | ||
| name: string, | ||
| libraryConfig: ThirdPartyLibraryConfig, | ||
| timeoutStr?: string, | ||
| memoryStr?: string | ||
| ): EvaluatorConfig { | ||
| const timeoutSeconds = timeoutStr ? parseInt(timeoutStr, 10) : libraryConfig.defaultTimeoutSeconds; | ||
| const memorySizeMb = memoryStr ? parseInt(memoryStr, 10) : libraryConfig.defaultMemorySizeMb; | ||
| return { | ||
| codeBased: { | ||
| managed: { | ||
| codeLocation: `app/${name}/`, | ||
| entrypoint: DEFAULT_CODE_ENTRYPOINT, | ||
| timeoutSeconds, | ||
| memorySizeMb, | ||
| additionalPolicies: ['execution-role-policy.json'], | ||
| }, | ||
| }, | ||
| }; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
--param key=value(repeatable) and--parameters-filefor metric constructor kwargslambda_function.py+pyproject.toml+execution-role-policy.jsonTest plan
npx vitest run src/cli/primitives/__tests__/EvaluatorPrimitive.test.ts)e2e-tests/third-party-eval-lifecycle.test.ts(DeepEval + Autoevals full lifecycle)Customer experience